home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / xulrunner-1.9.0.14 / chrome / pippki.jar / content / pippki / device_manager.js < prev    next >
Encoding:
Text File  |  2009-08-11  |  17.6 KB  |  552 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is mozilla.org code.
  15.  *
  16.  * The Initial Developer of the Original Code is
  17.  * Netscape Communications Corporation.
  18.  * Portions created by the Initial Developer are Copyright (C) 2001
  19.  * the Initial Developer. All Rights Reserved.
  20.  *
  21.  * Contributor(s):
  22.  *   Bob Lord <lord@netscape.com>
  23.  *   Ian McGreer <mcgreer@netscape.com>
  24.  *   Kai Engert <kengert@redhat.com>
  25.  *
  26.  * Alternatively, the contents of this file may be used under the terms of
  27.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  28.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  29.  * in which case the provisions of the GPL or the LGPL are applicable instead
  30.  * of those above. If you wish to allow use of your version of this file only
  31.  * under the terms of either the GPL or the LGPL, and not to allow others to
  32.  * use your version of this file under the terms of the MPL, indicate your
  33.  * decision by deleting the provisions above and replace them with the notice
  34.  * and other provisions required by the GPL or the LGPL. If you do not delete
  35.  * the provisions above, a recipient may use your version of this file under
  36.  * the terms of any one of the MPL, the GPL or the LGPL.
  37.  *
  38.  * ***** END LICENSE BLOCK ***** */
  39.  
  40. const nsIFilePicker = Components.interfaces.nsIFilePicker;
  41. const nsFilePicker = "@mozilla.org/filepicker;1";
  42. const nsIPKCS11Slot = Components.interfaces.nsIPKCS11Slot;
  43. const nsIPKCS11Module = Components.interfaces.nsIPKCS11Module;
  44. const nsPKCS11ModuleDB = "@mozilla.org/security/pkcs11moduledb;1";
  45. const nsIPKCS11ModuleDB = Components.interfaces.nsIPKCS11ModuleDB;
  46. const nsIPK11Token = Components.interfaces.nsIPK11Token;
  47. const nsPK11TokenDB = "@mozilla.org/security/pk11tokendb;1";
  48. const nsIPK11TokenDB = Components.interfaces.nsIPK11TokenDB;
  49. const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock;
  50. const nsDialogParamBlock = "@mozilla.org/embedcomp/dialogparam;1";
  51. const nsIPKCS11 = Components.interfaces.nsIPKCS11;
  52. const nsPKCS11ContractID = "@mozilla.org/security/pkcs11;1";
  53.  
  54. var bundle;
  55. var secmoddb;
  56. var skip_enable_buttons = false;
  57.  
  58. /* Do the initial load of all PKCS# modules and list them. */
  59. function LoadModules()
  60. {
  61.   bundle = srGetStrBundle("chrome://pippki/locale/pippki.properties");
  62.   secmoddb = Components.classes[nsPKCS11ModuleDB].getService(nsIPKCS11ModuleDB);
  63.   window.crypto.enableSmartCardEvents = true;
  64.   document.addEventListener("smartcard-insert", onSmartCardChange, false);
  65.   document.addEventListener("smartcard-remove", onSmartCardChange, false);
  66.  
  67.   RefreshDeviceList();
  68. }
  69.  
  70. function getPKCS11()
  71. {
  72.   return Components.classes[nsPKCS11ContractID].getService(nsIPKCS11);
  73. }
  74.  
  75. function getNSSString(name)
  76. {
  77.   return srGetStrBundle("chrome://pipnss/locale/pipnss.properties").
  78.     GetStringFromName(name);
  79. }
  80.  
  81. function doPrompt(msg)
  82. {
  83.   let prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
  84.     getService(Components.interfaces.nsIPromptService);
  85.   prompts.alert(window, null, msg);
  86. }
  87.  
  88. function doConfirm(msg)
  89. {
  90.   let prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
  91.     getService(Components.interfaces.nsIPromptService);
  92.   return prompts.confirm(window, null, msg);
  93. }
  94.  
  95. function RefreshDeviceList()
  96. {
  97.   var modules = secmoddb.listModules();
  98.   var done = false;
  99.  
  100.   try {
  101.     modules.isDone();
  102.   } catch (e) { done = true; }
  103.   while (!done) {
  104.     var module = modules.currentItem().QueryInterface(nsIPKCS11Module);
  105.     if (module) {
  106.       var slotnames = [];
  107.       var slots = module.listSlots();
  108.       var slots_done = false;
  109.       try {
  110.         slots.isDone();
  111.       } catch (e) { slots_done = true; }
  112.       while (!slots_done) {
  113.         var slot = null;
  114.      try {
  115.           slot = slots.currentItem().QueryInterface(nsIPKCS11Slot);
  116.         } catch (e) { slot = null; }
  117.         // in the ongoing discussion of whether slot names or token names
  118.         // are to be shown, I've gone with token names because NSS will
  119.         // prefer lookup by token name.  However, the token may not be
  120.         // present, so maybe slot names should be listed, while token names
  121.         // are "remembered" for lookup?
  122.     if (slot != null) {
  123.           if (slot.tokenName)
  124.             slotnames[slotnames.length] = slot.tokenName;
  125.           else
  126.             slotnames[slotnames.length] = slot.name;
  127.     }
  128.         try {
  129.           slots.next();
  130.         } catch (e) { slots_done = true; }
  131.       }
  132.       AddModule(module.name, slotnames);
  133.     }
  134.     try {
  135.       modules.next();
  136.     } catch (e) { done = true; }
  137.   }
  138.   /* Set the text on the fips button */
  139.   SetFIPSButton();
  140. }
  141.  
  142. function SetFIPSButton()
  143. {
  144.   var fipsButton = document.getElementById("fipsbutton");
  145.   var label;
  146.   if (secmoddb.isFIPSEnabled) {
  147.    label = bundle.GetStringFromName("disable_fips"); 
  148.   } else {
  149.    label = bundle.GetStringFromName("enable_fips"); 
  150.   }
  151.   fipsButton.setAttribute("label", label);
  152.  
  153.   var can_toggle = secmoddb.canToggleFIPS;
  154.   if (can_toggle) {
  155.     fipsButton.removeAttribute("disabled");
  156.   } else {
  157.     fipsButton.setAttribute("disabled", "true");
  158.   }
  159. }
  160.  
  161. /* Add a module to the tree.  slots is the array of slots in the module,
  162.  * to be represented as children.
  163.  */
  164. function AddModule(module, slots)
  165. {
  166.   var tree = document.getElementById("device_list");
  167.   var item  = document.createElement("treeitem");
  168.   var row  = document.createElement("treerow");
  169.   var cell = document.createElement("treecell");
  170.   cell.setAttribute("label", module);
  171.   row.appendChild(cell);
  172.   item.appendChild(row);
  173.   var parent = document.createElement("treechildren");
  174.   for (var i = 0; i<slots.length; i++) {
  175.     var child_item = document.createElement("treeitem");
  176.     var child_row = document.createElement("treerow");
  177.     var child_cell = document.createElement("treecell");
  178.     child_cell.setAttribute("label", slots[i]);
  179.     child_row.appendChild(child_cell);
  180.     child_item.appendChild(child_row);
  181.     child_item.setAttribute("pk11kind", "slot");
  182.     parent.appendChild(child_item);
  183.   }
  184.   item.appendChild(parent);
  185.   item.setAttribute("pk11kind", "module");
  186.   item.setAttribute("open", "true");
  187.   item.setAttribute("container", "true");
  188.   tree.appendChild(item);
  189. }
  190.  
  191. var selected_slot;
  192. var selected_module;
  193.  
  194. /* get the slot selected by the user (can only be one-at-a-time) */
  195. function getSelectedItem()
  196. {
  197.   var tree = document.getElementById('device_tree');
  198.   if (tree.currentIndex < 0) return;
  199.   var item = tree.contentView.getItemAtIndex(tree.currentIndex);
  200.   selected_slot = null;
  201.   selected_module = null;
  202.   if (item) {
  203.     var kind = item.getAttribute("pk11kind");
  204.     var module_name;
  205.     if (kind == "slot") {
  206.       // get the module cell for this slot cell
  207.       var cell = item.parentNode.parentNode.firstChild.firstChild;
  208.       module_name = cell.getAttribute("label");
  209.       var module = secmoddb.findModuleByName(module_name);
  210.       // get the cell for the selected row (the slot to display)
  211.       cell = item.firstChild.firstChild;
  212.       var slot_name = cell.getAttribute("label");
  213.       selected_slot = module.findSlotByName(slot_name);
  214.     } else { // (kind == "module")
  215.       // get the cell for the selected row (the module to display)
  216.       cell = item.firstChild.firstChild;
  217.       module_name = cell.getAttribute("label");
  218.       selected_module = secmoddb.findModuleByName(module_name);
  219.     }
  220.   }
  221. }
  222.  
  223. function enableButtons()
  224. {
  225.   if (skip_enable_buttons)
  226.     return;
  227.  
  228.   var login_toggle = "true";
  229.   var logout_toggle = "true";
  230.   var pw_toggle = "true";
  231.   var unload_toggle = "true";
  232.   getSelectedItem();
  233.   if (selected_module) {
  234.     unload_toggle = "false";
  235.     showModuleInfo();
  236.   } else if (selected_slot) {
  237.     // here's the workaround - login functions are all with token,
  238.     // so grab the token type
  239.     var selected_token = selected_slot.getToken();
  240.     if (selected_token != null) {
  241.       if (selected_token.needsLogin() || !(selected_token.needsUserInit)) {
  242.         pw_toggle = "false";
  243.         if(selected_token.needsLogin()) {
  244.           if (selected_token.isLoggedIn()) {
  245.             logout_toggle = "false";
  246.           } else {
  247.             login_toggle = "false";
  248.           }
  249.         }
  250.       }
  251.     }
  252.     showSlotInfo();
  253.   }
  254.   var thebutton = document.getElementById('login_button');
  255.   thebutton.setAttribute("disabled", login_toggle);
  256.   thebutton = document.getElementById('logout_button');
  257.   thebutton.setAttribute("disabled", logout_toggle);
  258.   thebutton = document.getElementById('change_pw_button');
  259.   thebutton.setAttribute("disabled", pw_toggle);
  260.   thebutton = document.getElementById('unload_button');
  261.   thebutton.setAttribute("disabled", unload_toggle);
  262.   // not implemented
  263.   //thebutton = document.getElementById('change_slotname_button');
  264.   //thebutton.setAttribute("disabled", toggle);
  265. }
  266.  
  267. // clear the display of information for the slot
  268. function ClearInfoList()
  269. {
  270.   var info_list = document.getElementById("info_list");
  271.   while (info_list.firstChild)
  272.       info_list.removeChild(info_list.firstChild);
  273. }
  274.  
  275. function ClearDeviceList()
  276. {
  277.   ClearInfoList();
  278.  
  279.   skip_enable_buttons = true;
  280.   var tree = document.getElementById('device_tree');
  281.   tree.view.selection.clearSelection();
  282.   skip_enable_buttons = false;
  283.  
  284.   // Remove the existing listed modules so that refresh doesn't 
  285.   // display the module that just changed.
  286.   var device_list = document.getElementById("device_list");
  287.   while (device_list.hasChildNodes())
  288.     device_list.removeChild(device_list.firstChild);
  289. }
  290.  
  291.  
  292. // show a list of info about a slot
  293. function showSlotInfo()
  294. {
  295.   var present = true;
  296.   ClearInfoList();
  297.   switch (selected_slot.status) {
  298.    case nsIPKCS11Slot.SLOT_DISABLED:
  299.      AddInfoRow(bundle.GetStringFromName("devinfo_status"), 
  300.                 bundle.GetStringFromName("devinfo_stat_disabled"), 
  301.                 "tok_status");
  302.      present = false;
  303.      break;
  304.    case nsIPKCS11Slot.SLOT_NOT_PRESENT:
  305.      AddInfoRow(bundle.GetStringFromName("devinfo_status"), 
  306.                 bundle.GetStringFromName("devinfo_stat_notpresent"), 
  307.                 "tok_status");
  308.      present = false;
  309.      break;
  310.    case nsIPKCS11Slot.SLOT_UNINITIALIZED:
  311.      AddInfoRow(bundle.GetStringFromName("devinfo_status"), 
  312.                 bundle.GetStringFromName("devinfo_stat_uninitialized"), 
  313.                 "tok_status");
  314.      break;
  315.    case nsIPKCS11Slot.SLOT_NOT_LOGGED_IN:
  316.      AddInfoRow(bundle.GetStringFromName("devinfo_status"), 
  317.                 bundle.GetStringFromName("devinfo_stat_notloggedin"), 
  318.                 "tok_status");
  319.      break;
  320.    case nsIPKCS11Slot.SLOT_LOGGED_IN:
  321.      AddInfoRow(bundle.GetStringFromName("devinfo_status"), 
  322.                 bundle.GetStringFromName("devinfo_stat_loggedin"), 
  323.                 "tok_status");
  324.      break;
  325.    case nsIPKCS11Slot.SLOT_READY:
  326.      AddInfoRow(bundle.GetStringFromName("devinfo_status"), 
  327.                 bundle.GetStringFromName("devinfo_stat_ready"), 
  328.                 "tok_status");
  329.      break;
  330.   }
  331.   AddInfoRow(bundle.GetStringFromName("devinfo_desc"), 
  332.              selected_slot.desc, "slot_desc");
  333.   AddInfoRow(bundle.GetStringFromName("devinfo_manID"), 
  334.              selected_slot.manID, "slot_manID");
  335.   AddInfoRow(bundle.GetStringFromName("devinfo_hwversion"),
  336.              selected_slot.HWVersion, "slot_hwv");
  337.   AddInfoRow(bundle.GetStringFromName("devinfo_fwversion"),
  338.              selected_slot.FWVersion, "slot_fwv");
  339.   if (present) {
  340.      showTokenInfo();
  341.   }
  342. }
  343.  
  344. function showModuleInfo()
  345. {
  346.   ClearInfoList();
  347.   AddInfoRow(bundle.GetStringFromName("devinfo_modname"),
  348.              selected_module.name, "module_name");
  349.   AddInfoRow(bundle.GetStringFromName("devinfo_modpath"),
  350.              selected_module.libName, "module_path");
  351. }
  352.  
  353. // add a row to the info list, as [col1 col2] (ex.: ["status" "logged in"])
  354. function AddInfoRow(col1, col2, cell_id)
  355. {
  356.   var tree = document.getElementById("info_list");
  357.   var item  = document.createElement("treeitem");
  358.   var row  = document.createElement("treerow");
  359.   var cell1 = document.createElement("treecell");
  360.   cell1.setAttribute("label", col1);
  361.   cell1.setAttribute("crop", "never");
  362.   row.appendChild(cell1);
  363.   var cell2 = document.createElement("treecell");
  364.   cell2.setAttribute("label", col2);
  365.   cell2.setAttribute("crop", "never");
  366.   cell2.setAttribute("id", cell_id);
  367.   row.appendChild(cell2);
  368.   item.appendChild(row);
  369.   tree.appendChild(item);
  370. }
  371.  
  372. // log in to a slot
  373. function doLogin()
  374. {
  375.   getSelectedItem();
  376.   // here's the workaround - login functions are with token
  377.   var selected_token = selected_slot.getToken();
  378.   try {
  379.     selected_token.login(false);
  380.     var tok_status = document.getElementById("tok_status");
  381.     if (selected_token.isLoggedIn()) {
  382.       tok_status.setAttribute("label", 
  383.                           bundle.GetStringFromName("devinfo_stat_loggedin"));
  384.     } else {
  385.       tok_status.setAttribute("label",
  386.                        bundle.GetStringFromName("devinfo_stat_notloggedin"));
  387.     }
  388.   } catch (e) {
  389.     var alertStr = bundle.GetStringFromName("login_failed"); 
  390.     alert(alertStr);
  391.   }
  392.   enableButtons();
  393. }
  394.  
  395. // log out of a slot
  396. function doLogout()
  397. {
  398.   getSelectedItem();
  399.   // here's the workaround - login functions are with token
  400.   var selected_token = selected_slot.getToken();
  401.   try {
  402.     selected_token.logoutAndDropAuthenticatedResources();
  403.     var tok_status = document.getElementById("tok_status");
  404.     if (selected_token.isLoggedIn()) {
  405.       tok_status.setAttribute("label", 
  406.                           bundle.GetStringFromName("devinfo_stat_loggedin"));
  407.     } else {
  408.       tok_status.setAttribute("label",
  409.                        bundle.GetStringFromName("devinfo_stat_notloggedin"));
  410.     }
  411.   } catch (e) {
  412.   }
  413.   enableButtons();
  414. }
  415.  
  416. // load a new device
  417. function doLoad()
  418. {
  419.   window.open("load_device.xul", "loaddevice", 
  420.               "chrome,centerscreen,modal");
  421.   ClearDeviceList();
  422.   RefreshDeviceList();
  423. }
  424.  
  425. function deleteSelected()
  426. {
  427.   getSelectedItem();
  428.   if (selected_module &&
  429.       doConfirm(getNSSString("DelModuleWarning"))) {
  430.     try {
  431.       getPKCS11().deleteModule(selected_module.name);
  432.     }
  433.     catch (e) {
  434.       doPrompt(getNSSString("DelModuleError"));
  435.       return false;
  436.     }
  437.     selected_module = null;
  438.     return true;
  439.   }
  440.   return false;
  441. }
  442.  
  443. function doUnload()
  444. {
  445.   if (deleteSelected()) {
  446.     ClearDeviceList();
  447.     RefreshDeviceList();
  448.   }
  449. }
  450.  
  451. // handle card insertion and removal
  452. function onSmartCardChange()
  453. {
  454.   var tree = document.getElementById('device_tree');
  455.   var index = tree.currentIndex;
  456.   tree.currentIndex = 0;
  457.   ClearDeviceList();
  458.   RefreshDeviceList();
  459.   tree.currentIndex = index;
  460.   enableButtons();
  461. }
  462.  
  463. function changePassword()
  464. {
  465.   getSelectedItem();
  466.   var params = Components.classes[nsDialogParamBlock].createInstance(nsIDialogParamBlock);
  467.   params.SetString(1,selected_slot.tokenName);
  468.   window.openDialog("changepassword.xul",
  469.               "", 
  470.               "chrome,centerscreen,modal", params);
  471.   showSlotInfo();
  472.   enableButtons();
  473. }
  474.  
  475. // browse fs for PKCS#11 device
  476. function doBrowseFiles()
  477. {
  478.   var srbundle = srGetStrBundle("chrome://pippki/locale/pippki.properties");
  479.   var fp = Components.classes[nsFilePicker].createInstance(nsIFilePicker);
  480.   fp.init(window,
  481.           srbundle.GetStringFromName("loadPK11TokenDialog"),
  482.           nsIFilePicker.modeOpen);
  483.   fp.appendFilters(nsIFilePicker.filterAll);
  484.   if (fp.show() == nsIFilePicker.returnOK) {
  485.     var pathbox = document.getElementById("device_path");
  486.     pathbox.setAttribute("value", fp.file.persistentDescriptor);
  487.   }
  488. }
  489.  
  490. function doLoadDevice()
  491. {
  492.   var name_box = document.getElementById("device_name");
  493.   var path_box = document.getElementById("device_path");
  494.   try {
  495.     getPKCS11().addModule(name_box.value, path_box.value, 0,0);
  496.   }
  497.   catch (e) {
  498.     if (e.result == Components.results.NS_ERROR_ILLEGAL_VALUE)
  499.       doPrompt(getNSSString("AddModuleDup"));
  500.     else
  501.       doPrompt(getNSSString("AddModuleFailure"));
  502.  
  503.     return false;
  504.   }
  505.   return true;
  506. }
  507.  
  508. // -------------------------------------   Old code
  509.  
  510. function showTokenInfo()
  511. {
  512.   //ClearInfoList();
  513.   var selected_token = selected_slot.getToken();
  514.   AddInfoRow(bundle.GetStringFromName("devinfo_label"), 
  515.              selected_token.tokenLabel, "tok_label");
  516.   AddInfoRow(bundle.GetStringFromName("devinfo_manID"),
  517.              selected_token.tokenManID, "tok_manID");
  518.   AddInfoRow(bundle.GetStringFromName("devinfo_serialnum"), 
  519.              selected_token.tokenSerialNumber, "tok_sNum");
  520.   AddInfoRow(bundle.GetStringFromName("devinfo_hwversion"),
  521.              selected_token.tokenHWVersion, "tok_hwv");
  522.   AddInfoRow(bundle.GetStringFromName("devinfo_fwversion"),
  523.              selected_token.tokenFWVersion, "tok_fwv");
  524. }
  525.  
  526. function toggleFIPS()
  527. {
  528.   if (!secmoddb.isFIPSEnabled) {
  529.     // A restriction of FIPS mode is, the password must be set
  530.     // In FIPS mode the password must be non-empty.
  531.     // This is different from what we allow in NON-Fips mode.
  532.  
  533.     var tokendb = Components.classes[nsPK11TokenDB].getService(nsIPK11TokenDB);
  534.     var internal_token = tokendb.getInternalKeyToken(); // nsIPK11Token
  535.     var slot = secmoddb.findSlotByName(internal_token.tokenName);
  536.     switch (slot.status) {
  537.       case nsIPKCS11Slot.SLOT_UNINITIALIZED:
  538.       case nsIPKCS11Slot.SLOT_READY:
  539.         // Token has either no or an empty password.
  540.         alert(bundle.GetStringFromName("fips_nonempty_password_required"));
  541.         return;
  542.     }
  543.   }
  544.   
  545.   secmoddb.toggleFIPSMode();
  546.   //Remove the existing listed modules so that re-fresh doesn't 
  547.   //display the module that just changed.
  548.   ClearDeviceList();
  549.  
  550.   RefreshDeviceList();
  551. }
  552.